<!--
 * @Author: 陆康永 email@email.com
 * @Date: 2024-11-13 14:50:27
 * @LastEditors: 陆康永 email@email.com
 * @LastEditTime: 2024-11-13 14:59:35
 * @FilePath: /数学/抛物线/index.html
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .line {
            height: 1px;
            width: 100%;
            left: 0;
            top: 420px;
            position: absolute;
            background: #000;
        }

        .line-top {
            width: 20px;
            top: 20px;
        }
    </style>
</head>

<body>
    <!-- 移动的元素 -->
    <div id="movingElement" style="width: 20px; height: 20px; background-color: red; position: absolute;"></div>
    <div class="line"></div>
    <div class="line line-top"></div>
    <script>
        // 抛物线方程应该基于时间进度 progress 来计算
        // y = start.y + (end.y−start.y)×(1−cos(π×progress))/2
        //这个方程使用了余弦函数来生成一个平滑的抛物线路径
        // 起始坐标和结束坐标
        const start = { x: 0, y: 0 };
        const end = { x: 500, y: 400 };

        // 移动的元素
        const movingElement = document.getElementById('movingElement');

        // 动画参数
        let startTime = null;
        const duration = 2000; // 动画持续时间，单位毫秒

        function animate(time) {
            if (!startTime) startTime = time;
            const elapsedTime = time - startTime;
            const progress = Math.min(elapsedTime / duration, 1);

            // 计算当前位置
            const x = start.x + (end.x - start.x) * progress;
            const y = start.y + (end.y - start.y) * (1 - Math.cos(Math.PI * progress)) / 2;

            // 设置元素位置
            movingElement.style.left = `${x}px`;
            movingElement.style.top = `${y}px`;

            // 如果动画未完成，继续动画
            if (progress < 1) {
                requestAnimationFrame(animate);
            }
        }

        // 开始动画
        requestAnimationFrame(animate);

        // 抛物线运动方程 \(y = \text{ start.y } + (\text{ end.y } - \text{ start.y }) \times(1 - \cos(\pi \times \text{ progress })) / 2 \) 的目的是生成一个元素从起始点 \(\text{ start.y } \) 到终点 \(\text{ end.y } \) 的平滑抛物线路径。让我们逐步分析这个方程：

        //     1. ** 起始和结束点 **:
        //     - \(\text{ start.y } \) 是元素的初始垂直位置。
        //     - \(\text{ end.y } \) 是元素的最终垂直位置。

        //     2. ** 时间进度 **:
        //     - \(\text{ progress } \) 是一个从 0 到 1 变化的变量，表示动画的完成度。在动画开始时，\(\text{ progress } = 0 \)，在动画结束时，\(\text{ progress } = 1 \)。

        //     3. ** 余弦函数 **:
        //     - \(\cos(\pi \times \text{ progress }) \) 是余弦函数，它在 \(\text{ progress } \) 从 0 到 1 变化时，从 1 变化到 - 1。余弦函数的周期是 \(2\pi \)，但在这里我们使用 \(\pi \) 来确保它在 \(\text{ progress } \) 从 0 到 1 时完成一个完整的周期。

        //     4. ** 抛物线形状 **:
        //     - \(1 - \cos(\pi \times \text{ progress }) \) 将余弦函数的输出从 1 到 - 1 转换为 0 到 2。这创建了一个对称的抛物线形状，其中在 \(\text{ progress } = 0 \) 时值为 0，在 \(\text{ progress } = 0.5 \) 时达到最大值 2，在 \(\text{ progress } = 1 \) 时回到 0。

        //     5. ** 归一化 **:
        //     - \((1 - \cos(\pi \times \text{ progress })) / 2 \) 将值从 0 到 2 归一化为 0 到 1。这确保了抛物线在 \( \text{progress} = 0 \) 和 \( \text{progress} = 1 \) 时分别达到起始和结束点。

        //     6. ** 最终计算 **:
        //     - \(\text{ start.y } + (\text{ end.y } - \text{ start.y }) \times(1 - \cos(\pi \times \text{ progress })) / 2 \) 计算元素在任何给定时间 \(\text{ progress } \) 的垂直位置。它从起始位置开始，并根据抛物线方程添加一个从 0 到 \(\text{ end.y } - \text{ start.y } \) 变化的值。

        //     这个方程确保了元素沿着一个平滑的抛物线路径移动，从起始点到终点，提供了一个视觉上吸引人的动画效果。

    </script>
</body>

</html>